package model;
import controller.PhysicsEngine;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;

import javax.imageio.ImageIO;

public class Map implements Serializable
{
        private PhysicsEngine engine = new PhysicsEngine();
        
        private Puck puck;
        private ArrayList<Bar> bars = new ArrayList<Bar>();
        private ArrayList<Goal> goals = new ArrayList<Goal>();
        private ArrayList<Coin> coins = new ArrayList<Coin>();
        private ArrayList<Block> blocks = new ArrayList<Block>();
        
        private transient BufferedImage background;
        private String filename;
        private String type;
        private int scoreLimit;
        private int timeAttack;
        private int userScore;
        private int AIScore;
        
        private int[] coinCounter = new int[8];
        
        public Map()
        {
                filename = "";
                background = null;
                type = "scoreLimit";
                
                userScore = 0;
                AIScore = 0;
                
                for(int i = 0; i < 8; ++i)
                        coinCounter[i] = -1;
                
        }
        
        public Map(String file) throws Exception
        {
                FileInputStream fileIn = new FileInputStream(file);
                ObjectInputStream inStream = new ObjectInputStream(fileIn);
                
                ArrayList<Puck> temp = (ArrayList<Puck>)inStream.readObject();
                puck = temp.get(0);
                bars = (ArrayList<Bar>)inStream.readObject();
                goals = (ArrayList<Goal>)inStream.readObject();
                coins = (ArrayList<Coin>)inStream.readObject();
                blocks = (ArrayList<Block>)inStream.readObject();
                
                inStream.close();
                
                for(int i = 0; i < 8; ++i)
                        coinCounter[i] = -1;
        }
        
        public void construct(String file) throws Exception
        {
                FileInputStream fileIn = new FileInputStream(file);
                ObjectInputStream inStream = new ObjectInputStream(fileIn);
                
                ArrayList<Puck> temp = (ArrayList<Puck>)inStream.readObject();
                puck = temp.get(0);
                bars = (ArrayList<Bar>)inStream.readObject();
                goals = (ArrayList<Goal>)inStream.readObject();
                coins = (ArrayList<Coin>)inStream.readObject();
                blocks = (ArrayList<Block>)inStream.readObject();
                
                inStream.close();
                
                for(int i = 0; i < 8; ++i)
                        coinCounter[i] = -1;

        }
        
        public void load(Puck puck, ArrayList<Bar> bars, ArrayList<Goal> goals, ArrayList<Coin> coins, ArrayList<Block> blocks, String filename, String type)
        {
                this.puck = puck;
                this.bars = bars;
                this.goals = goals;
                this.coins = coins;
                this.blocks = blocks;
                this.type = type;
                this.filename = filename;
                
                if(type.equals("scorelimit"))
                {
                        scoreLimit = 200;
                        timeAttack = -1;
                }
                else
                {
                        scoreLimit = -1;
                        timeAttack = 60;
                }

                try{
                        background = ImageIO.read(new File(filename));
                } catch(IOException e){ 
                }
                
                for(int i = 0; i < 8; ++i)
                        coinCounter[i] = -1;
        }
        
        public void modifyCoinCounter(int index, int value)
        {
                coinCounter[index] = value;
        }
        
        public int getCoinCounterIndex(int index)
        {
                return coinCounter[index];
        }
        
        public void addUserScore(int score)
        {
                userScore += score;
        }
        
        public void addAIScore(int score)
        {
                AIScore += score;
        }
        
        public int getUserScore()
        {
                return userScore;
        }
        
        public int getAIScore()
        {
                return AIScore;
        }
        
        public void addObject(Puck puck)
        {
                this.puck = puck;
        }
        
        public void addObject(Bar bar)
        {
                if(!(bars.contains(bar)))
                        bars.add(bar);
        }
        
        public void addObject(Goal goal)
        {
                if(!(goals.contains(goal)))
                        goals.add(goal);
        }
        
        public void addObject(Coin coin)
        {
                if(!(coins.contains(coin)))
                        coins.add(coin);
        }
        
        public void addObject(Block block)
        {
                if(!(blocks.contains(block)))
                        blocks.add(block);
        }
        
        public void removeObject(GameObject obj)
        {
                if(bars.contains(obj))
                        bars.remove(obj);
                else if(goals.contains(obj))
                        goals.remove(obj);
                else if(coins.contains(obj))
                        coins.remove(obj);
                else
                        blocks.remove(obj);
        }
        
        public void setBackground(String filename)
        {
                this.filename = filename;
                
                try{
                        background = ImageIO.read(new File(filename));
                } catch(IOException e){ 
                }
                
        }
        
        public String getFilename()
        {
                return filename;
        }
        
        public BufferedImage getBackground()
        {
                return background;
        }
        
        public void setTimeAttack()
        {
                type = "timeAttack";
                timeAttack = 60;
                scoreLimit = 1;
        }
        
        public void setScoreLimit()
        {
                type = "scoreLimit";
                timeAttack = -1;
                scoreLimit = 200;
        }
        
        public String getGameType()
        {
                return type;
        }
        
        public int getScoreLimit()
        {
                return scoreLimit;
        }
        
        public int getTimeLimit()
        {
                return timeAttack;
        }
        
        public Puck getPuck()
        {
                return puck;
        }
        
        public ArrayList<Bar> getBars()
        {
                return bars;
        }
        
        public ArrayList<Goal> getGoals()
        {
                return goals;
        }
        
        public ArrayList<Coin> getCoins()
        {
                return coins;
        }
        
        public ArrayList<Block> getBlocks()
        {
                return blocks;
        }
        
        public void refresh()
        {
                for(int i = 0; i < 8; ++i)
                {
                        if(coinCounter[i] > 0)
                                coinCounter[i] = coinCounter[i] - 1;
                                                
                        if(coinCounter[i] == 0)
                        {
                                switch(i) {
                                case 0:
                                        bars.get(1).setVisibility(true);
                                        modifyCoinCounter(0, -1);
                                        break;
                                case 1:
                                        bars.get(1).setDimX(60);
                                        bars.get(1).changeImage("AIBar.png");
                                        modifyCoinCounter(1, -1);
                                        break;
                                case 2:
                                        ((UserBar)bars.get(0)).setCoeff(0);
                                        modifyCoinCounter(2, -1);
                                        break;
                                case 4:
                                        bars.get(0).setVisibility(true);
                                        modifyCoinCounter(4, -1);
                                        break;
                                case 5:
                                        bars.get(0).setDimX(60);
                                        bars.get(0).changeImage("UserBarDefault.png");
                                        modifyCoinCounter(5, -1);
                                        break;
                                case 6:
                                        ((UserBar)bars.get(0)).setCoeff(0);
                                        modifyCoinCounter(6, -1);
                                        break;
                                default:
                                        break;
                                }
                        }
                        
                }
        }
        
        public void update(int input)
        {
                puck.update();
                
                ((UserBar)bars.get(0)).update(input);
                ((AIBar)bars.get(1)).update(puck.getVect());
                
                for(Goal goal : goals)
                        goal.update();
                
                for(Coin coin : coins)
                        coin.update();
                
                for(Block block : blocks)
                        block.update();
        }
        
        public void drawObjects(Graphics page)
        {
                puck.draw(page);
                
                for(Bar bar : bars)
                        bar.draw(page);
                
                for(Goal goal : goals)
                        goal.draw(page);
                
                for(Coin coin : coins)
                        coin.draw(page);
                
                for(Block block : blocks)
                        block.draw(page);
        }
        

}